package ldh.im.rpc.connection.server;

import ldh.im.rpc.config.RpcConfig;
import ldh.im.rpc.connection.RpcCallback;
import ldh.im.rpc.connection.RpcServiceProxy;
import ldh.im.rpc.dto.RpcData;
import ldh.im.rpc.exception.RpcErrorCode;
import ldh.im.rpc.exception.RpcException;

import java.nio.channels.Channel;
import java.util.concurrent.TimeoutException;

public class RpcServerServiceProxy extends RpcServiceProxy {

    public RpcServerServiceProxy(Class rpcServiceClazz, RpcConfig rpcConfig) {
        super(rpcServiceClazz, rpcConfig);
    }

    @Override
    public Object write(RpcData rpcData, int readTimeout, Object[] args) throws InterruptedException, TimeoutException {
        RpcCallback rpcCallback = getRpcCallback(args);
        Channel channel = getRpcChannelParam(rpcData, args);
        Object data = getRpcDataParam(rpcData, args, rpcCallback);
        rpcData.setData(data);
        readTimeout = readTimeout < 1 ? rpcConfig.getReadTimeout() : readTimeout;
        RpcServerConnection rpcClientConnection = (RpcServerConnection) rpcConfig.getRpcConnection();
        if (rpcCallback != null) {
            rpcClientConnection.writeForCallback(channel, rpcData, rpcCallback);
            return null;
        }
        return rpcClientConnection.write(channel, rpcData, readTimeout);
    }

    private Channel getRpcChannelParam(RpcData rpcData, Object[] args) {
        for (Object object : args) {
            if (object instanceof Channel) {
                return (Channel) object;
            }
        }

        throw new IllegalArgumentException("RpcServerProxy代理传输参数必须只有一个Channel对象");
    }

    private Object getRpcDataParam(RpcData rpcData, Object[] args, RpcCallback rpcCallback) {
        if ((args.length != 2 && rpcCallback == null) || (args.length != 3 && rpcCallback != null)) {
            throw new RpcException(RpcErrorCode.Api_error, rpcData.getPath());
        }

        for (Object object : args) {
            if (!(object instanceof Channel) && (object != rpcCallback)) {
                return object;
            }
        }

        throw new IllegalArgumentException("RpcServerProxy代理传输参数只有一个Channel对象");
    }
}
